package com.acc.mobileappr.scheduler.jobs;

import com.acc.mobileappr.constant.AppConstant;
import com.acc.mobileappr.entities.TrnMApprRequestEntity;
import com.acc.mobileappr.util.PushUtil;
import com.acc.mobileappr.util.Util;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import java.util.Date;
import java.util.List;

/**
 * Retrial Job
 * Abiel@ICN
 */
public class RetryJob implements Job {

    private static EntityManagerFactory factory;
     static final Logger logger = Logger.getLogger(RetryJob.class);

     /**
     * constructor
     */
    public RetryJob() {
        factory = Persistence.createEntityManagerFactory(AppConstant.PERSISTENCE_UNIT_MAREX);
    }

    /**
     * Execute Job
     *
     * @param jobExecutionContext     job execution context
     * @throws JobExecutionException  job execution exception
     */
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        Util.print(" Retry job executed on" + new Date());
        runProcess();
    }


    /**
     * Run process
     */
    public void runProcess() {

        EntityManager em = factory.createEntityManager();
        Util.print("Retrying..");

        try {
            Query q = em.createQuery("select req from TrnMApprRequestEntity req where req.pushStatus='F' and req.retryRemain <> '0'");
            List<TrnMApprRequestEntity> list = q.getResultList();

            if (list.isEmpty()) {
                Util.print("No Failed push data to be sent");
            }else{

            int n = list.size();
            int x=1;
            for (TrnMApprRequestEntity item : list) {

                Util.print("Retrying push document no "+x+" of "+n);
                Util.print(item);

                em.getTransaction().begin();
                String userPin = item.getPin();
                String pushId = item.getPushId();

                PushUtil pushUtil = new PushUtil();
                pushUtil.pushData(userPin, pushId, item.getData());

                int retryRemain = Integer.parseInt(item.getRetryRemain());
                retryRemain--;

                //TODO : again, I dont like direct SQL call when talking about Abstraction
                Query q2 = em.createNativeQuery("UPDATE TRN_M_APPR_REQUEST SET RETRY_REMAIN=?1 , PUSH_STATUS=?2 WHERE PUSH_ID=?3")
                        .setParameter(1, retryRemain)
                        .setParameter(2, "Q")
                        .setParameter(3, pushId);

                q2.executeUpdate();
                em.getTransaction().commit();
                x++;

            }
                
             Util.print("Retry sending finished for this moment.");
          }

        } catch (Exception e) {
            e.printStackTrace();
            Util.error(e.getMessage());
        } finally {
            em.close();
        }
    }

}
